﻿using System;
using System.Web.UI.WebControls;
using DotNetNuke.Entities.Modules;
using System.Web.UI;
using System.Globalization;
using DotNetNuke.Services.Localization;
using DotNetNuke.UI.Skins.Controls;
using DotNetNuke.Entities.Host;
using DotNetNuke.Services.Exceptions;

namespace HeroldIT.Dnn.SkinObjects
{
    /// <summary>
    /// A base class for search skin objects
    /// </summary>
    public abstract class Search : PortalModuleBase, IButtonControl
    {
        #region fields

        /// <summary>
        /// Holds the search button control.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "btn", Justification = "We want the hungarian notation here.")]
        protected IButtonControl btnSearch;

        /// <summary>
        /// Holds the search text control.
        /// </summary>
        protected ITextControl txtSearch;

        #endregion

        #region methods

        /// <summary>
        /// Performs the search with the given search text.
        /// </summary>
        /// <param name="searchText">The text to search.</param>
        protected void PerformSearch(string searchText)
        {
            if (String.IsNullOrEmpty(searchText))
                return;

            int resultsTabId;

            if (null != this.Settings["SearchResultsModule"])
            {
                resultsTabId = int.Parse((string)this.Settings["SearchResultsModule"], CultureInfo.InvariantCulture);
            }
            else
            {
                var controller = new ModuleController();
                var searchModule = controller.GetModuleByDefinition(this.PortalSettings.PortalId, "Search Results");
                if (null == searchModule)
                {
                    DotNetNuke.UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("NoSearchModule"), ModuleMessage.ModuleMessageType.YellowWarning);
                    return;
                }

                resultsTabId = searchModule.TabID;
            }
            if (HostSettings.GetHostSetting("UseFriendlyUrls") == "Y")
            {
                Response.Redirect(String.Format(CultureInfo.InvariantCulture, "{0}?Search={1}", DotNetNuke.Common.Globals.NavigateURL(resultsTabId), this.Server.UrlEncode(searchText)));
            }
            else
            {
                Response.Redirect(String.Format(CultureInfo.InvariantCulture, "{0}&Search={1}", DotNetNuke.Common.Globals.NavigateURL(resultsTabId), this.Server.UrlEncode(searchText)));
            }
        }

        /// <summary>
        /// Fires the <see cref="System.Web.UI.Control.Init"/> event.
        /// </summary>
        /// <param name="e">The arguments to pass to the event.</param>
        protected override void OnInit(EventArgs e)
        {
            try
            {
                this.AssertRequiredControls();

                this.btnSearch.Click += this.btnSearch_Click;
            }
            catch (NotImplementedException niex)
            {
                Exceptions.ProcessModuleLoadException(this, niex);
            }

            base.OnInit(e);
        }

        private void AssertRequiredControls()
        {
            if (null == this.txtSearch)
            {
                throw new NotImplementedException("ITextControl 'txtSearch' is not supplied by the user control.");
            }
            if (null == this.btnSearch)
            {
                throw new NotImplementedException("IButtonControl 'btnSearch' is not supplied by the user control.");
            }
        }

        #region event handlers

        void btnSearch_Click(object sender, EventArgs e)
        {
            this.PerformSearch(this.txtSearch.Text);
        }

        #endregion

        #endregion

        #region IButtonControl Members

        ///<summary>
        ///Occurs when the button control is clicked.
        ///</summary>
        ///
        public event EventHandler Click
        {
            add { this.btnSearch.Click += value; }
            remove { this.btnSearch.Click -= value; }
        }

        ///<summary>
        ///Occurs when the button control is clicked.
        ///</summary>
        ///
        public event CommandEventHandler Command
        {
            add { this.btnSearch.Command += value; }
            remove { this.btnSearch.Command -= value; }
        }

        ///<summary>
        ///Gets or sets a value indicating whether clicking the button causes page validation to occur.
        ///</summary>
        ///
        ///<returns>
        ///true if clicking the button causes page validation to occur; otherwise, false.
        ///</returns>
        ///
        public bool CausesValidation
        {
            get { return this.btnSearch.CausesValidation; }
            set { this.btnSearch.CausesValidation = value; }
        }

        ///<summary>
        ///Gets or sets an optional argument that is propagated to the <see cref="E:System.Web.UI.WebControls.IButtonControl.Command"></see> event.
        ///</summary>
        ///
        ///<returns>
        ///The argument that is propagated to the <see cref="E:System.Web.UI.WebControls.IButtonControl.Command"></see> event.
        ///</returns>
        ///
        public string CommandArgument
        {
            get { return this.btnSearch.CommandArgument; }
            set { this.btnSearch.CommandArgument = value; }
        }

        ///<summary>
        ///Gets or sets the command name that is propagated to the <see cref="E:System.Web.UI.WebControls.IButtonControl.Command"></see> event.
        ///</summary>
        ///
        ///<returns>
        ///The name of the command that is propagated to the <see cref="E:System.Web.UI.WebControls.IButtonControl.Command"></see> event.
        ///</returns>
        ///
        public string CommandName
        {
            get { return this.btnSearch.CommandName; }
            set { this.btnSearch.CommandName = value; }
        }

        ///<summary>
        ///Gets or sets the URL of the Web page to post to from the current page when the button control is clicked.
        ///</summary>
        ///
        ///<returns>
        ///The URL of the Web page to post to from the current page when the button control is clicked.
        ///</returns>
        ///
        public string PostBackUrl
        {
            get { return this.btnSearch.PostBackUrl; }
            set { this.btnSearch.PostBackUrl = value; }
        }

        ///<summary>
        ///Gets or sets the text caption displayed for the button.
        ///</summary>
        ///
        ///<returns>
        ///The text caption displayed for the button.
        ///</returns>
        ///
        public string Text
        {
            get { return this.btnSearch.Text; }
            set { this.btnSearch.Text = value; }
        }

        ///<summary>
        ///Gets or sets the name for the group of controls for which the button control causes validation when it posts back to the server.
        ///</summary>
        ///
        ///<returns>
        ///The name for the group of controls for which the button control causes validation when it posts back to the server.
        ///</returns>
        ///
        public string ValidationGroup
        {
            get { return this.btnSearch.ValidationGroup; }
            set { this.btnSearch.ValidationGroup = value; }
        }

        #endregion
    }
}
